commonlibsse_ng\re\p/
PlayerCamera.rs1mod camera_state;
2mod runtime_data;
3mod runtime_data2;
4
5pub use self::camera_state::{
6 CameraState, CameraStateSE, CameraStateSE_CEnum, CameraStateVR, CameraStateVR_CEnum,
7};
8pub use self::runtime_data::{RUNTIME_DATA, Unk120, VR_RUNTIME_DATA};
9pub use self::runtime_data2::RUNTIME_DATA2;
10
11use crate::re::BSPointerHandle::ActorHandle;
12use crate::re::TESCamera::{TESCamera, TESCameraVtbl};
13use crate::re::offsets_rtti::RTTI_PlayerCamera;
14use crate::re::offsets_vtable::VTABLE_PlayerCamera;
15use crate::rel::id::VariantID;
16use crate::rel::module::is_vr;
17use crate::rel::relocation::{RelocationError, relocate_member, relocate_member_mut};
18
19#[repr(C)]
20#[derive(Debug, Clone, PartialEq)]
21pub struct PlayerCamera {
22 pub __base: TESCamera, pub pad39: u8, pub pad3A: u16, pub cameraTarget: ActorHandle, }
27const _: () = assert!(std::mem::size_of::<PlayerCamera>() == 0x40);
28
29macro_rules! define_runtime_getters {
31 (
32 $( {
33 fn_name: $getter:ident,
34 fn_name_mut: $getter_mut:ident,
35 type: $data_type:ty,
36 se_ae_offset: $se_ae_offset:expr,
37 vr_offset: $vr_offset:expr
38 } ),* $(,)?
39 ) => {
40 $(
41 #[inline]
47 pub fn $getter(&self) -> Result<&$data_type, RelocationError> {
48 relocate_member(self, $se_ae_offset, $vr_offset)
49 }
50
51 #[inline]
57 pub fn $getter_mut(&mut self) -> Result<&mut $data_type, RelocationError> {
58 relocate_member_mut(self, $se_ae_offset, $vr_offset)
59 }
60 )*
61 };
62}
63
64impl PlayerCamera {
65 pub const RTTI: VariantID = RTTI_PlayerCamera;
67
68 pub const VTABLE: [VariantID; 1] = VTABLE_PlayerCamera;
70
71 #[commonlibsse_ng_derive_internal::relocate(
73 cast_as = "*mut *mut PlayerCamera",
74 default = "None",
75 deref_once,
76 id(se = 514642, ae = 400802)
77 )]
78 pub fn get_singleton() -> Option<&'static PlayerCamera> {
79 |deref_type: DerefType| unsafe { deref_type.as_ref() }
80 }
81
82 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 49858, ae_id = 50790)]
83 #[inline]
84 pub fn force_first_person(&mut self) -> bool {
85 if is_vr() {
86 return false;
87 }
88 }
89
90 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 49863, ae_id = 50796)]
91 #[inline]
92 pub fn force_third_person(&mut self) -> bool {
93 if is_vr() {
94 return false;
95 }
96 }
97
98 #[inline]
99 pub fn is_in_bleedout_mode(&self) -> bool {
100 let is_vr = is_vr();
101 let state = if is_vr {
102 CameraStateVR::VRBleedout.to_state()
103 } else {
104 CameraStateSE::Bleedout.to_state()
105 };
106 self.q_camera_equals(state, is_vr)
107 }
108
109 #[inline]
110 pub fn is_in_first_person(&self) -> bool {
111 self.q_camera_equals(CameraStateSE::FirstPerson.to_state(), is_vr())
112 }
113
114 #[inline]
115 pub fn is_in_free_camera_mode(&self) -> bool {
116 self.q_camera_equals(CameraStateSE::Free.to_state(), is_vr())
117 }
118
119 #[inline]
120 pub fn is_in_third_person(&self) -> bool {
121 let is_vr = is_vr();
122 let state = if is_vr {
123 CameraStateVR::VRThirdPerson.to_state()
124 } else {
125 CameraStateSE::ThirdPerson.to_state()
126 };
127 self.q_camera_equals(state, is_vr)
128 }
129
130 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 49947, ae_id = 50880)]
131 #[inline]
132 pub fn push_camera_state(&mut self, state: CameraState) {}
133
134 #[inline]
135 pub fn q_camera_equals(&self, camera_state: CameraState, is_vr: bool) -> bool {
136 if self.__base.currentState.is_null() {
137 return false;
138 }
139
140 if is_vr {
141 match self.get_vr_runtime_data() {
142 Ok(runtime_data) => {
143 if let Some(state_index) = camera_state.as_vr() {
144 return !runtime_data.cameraStates[state_index as usize].is_null();
145 };
146 #[cfg(feature = "tracing")]
147 tracing::warn!(
148 "CameraState index for VR is 0..=13 is expected, but got `{}`.",
149 camera_state.0
150 );
151 }
152 Err(_err) => {
153 #[cfg(feature = "tracing")]
154 tracing::error!("{_err}");
155 }
156 }
157 return false;
158 }
159
160 match self.get_runtime_data() {
162 Ok(runtime_data) => {
163 if let Some(state_index) = camera_state.as_se() {
164 return !runtime_data.cameraStates[state_index as usize].is_null();
165 }
166 #[cfg(feature = "tracing")]
167 tracing::warn!(
168 "CameraState index for SE/AE is 0..=12 is expected, but got `{}`.",
169 camera_state.0
170 );
171 }
172 Err(_err) => {
173 #[cfg(feature = "tracing")]
174 tracing::error!("{_err}");
175 }
176 }
177 false
178 }
179
180 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 49876, ae_id = 50809)]
181 #[inline]
182 pub fn toggle_free_camera_mode(&mut self, freeze_time: bool) {}
183
184 #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 49908, ae_id = 50841)]
185 #[inline]
186 pub fn update_third_person(&mut self, weapon_drawn: bool) {}
187
188 define_runtime_getters! {
192 {
193 fn_name: get_runtime_data,
194 fn_name_mut: get_runtime_data_mut,
195 type: VR_RUNTIME_DATA,
196 se_ae_offset: 0x40,
197 vr_offset: 0
198 },
199 {
200 fn_name: get_runtime_data2,
201 fn_name_mut: get_runtime_data2_mut,
202 type: RUNTIME_DATA2,
203 se_ae_offset: 0x13C,
204 vr_offset: 0x158
205 },
206 {
207 fn_name: get_vr_runtime_data,
208 fn_name_mut: get_vr_runtime_data_mut,
209 type: VR_RUNTIME_DATA,
210 se_ae_offset: 0x0,
211 vr_offset: 0x40
212 },
213 }
214}
215
216#[repr(C)]
217#[derive(Debug)]
218pub struct PlayerCameraVtbl {
219 pub __base: TESCameraVtbl, }
221const _: () = {
222 const VFUNC_COUNT: usize = 0x3;
223
224 const EXPECTED_SIZE: usize = VFUNC_COUNT * core::mem::size_of::<usize>();
225 assert!(core::mem::size_of::<PlayerCameraVtbl>() == EXPECTED_SIZE);
226};